home *** CD-ROM | disk | FTP | other *** search
- ////////////////////////////////////////////////////////////
- // UNWIND.H
- // Copyright 1994 Gregory Colvin.
- // May be distributed free with this notice.
- #include <stdlib.h>
- #include <setjmp.h>
-
- // These macros emulate the corresponding C++ keywords.
- #define try \
- int eh_err=0; \
- { Handler Handler; \
- eh_err = setjmp(Handler.buf); \
- if (!eh_err)
- #define catch(dcl) \
- } \
- dcl = eh_err; \
- if (eh_err)
- #define throw(err) Handler::Throw(err)
-
- // Entry on stack of exception handlers.
- struct Handler {
- friend struct Pusher;
- friend struct Unwindable;
- Handler() : prev(handler), link(0) { handler = this; }
- ~Handler() { handler = handler->prev; }
- static void Throw(int); // throw an exception
- jmp_buf buf; // for use by try macro
- private:
- Handler* prev; // stack of handlers
- Unwindable* link; // stack of catchables
- static Handler* handler; // current handler
- static void push(Unwindable*,size_t);
- };
-
- // Pusher is used by the UNWINDABLE macro to make objects
- // catchable when their constructor is finished.
- struct Pusher {
- friend struct Unwindable;
- Pusher(Unwindable* p,size_t s) : pushed(p), size(s) {}
- ~Pusher() { Handler::push(pushed,size); }
- private:
- Unwindable* pushed;
- size_t size;
- };
- #define UNWINDABLE Pusher pusher(this,sizeof *this)
-
- // Unwindables can be destroyed when an exception is thrown.
- struct Unwindable {
- friend Handler;
- Unwindable() { UNWINDABLE; count++; }
- Unwindable(const Unwindable&) { UNWINDABLE; count++; }
- Unwindable& operator=(const Unwindable&) {
- UNWINDABLE;
- return *this;
- }
- virtual ~Unwindable() { --count; }
- void* operator new(size_t);
- void operator delete(void* p) { ::operator delete(p); }
- static unsigned Count() { return count; }
- private:
- Unwindable* link; // next object on stack
- size_t size; // size of complete object
- static unsigned count; // number of objects
- int within(Unwindable*);
- };
-
-
-